package com.rfid.transport;

import android.content.Context;

import com.ftdi.j2xx.D2xxManager;
import com.ftdi.j2xx.FT_Device;

public class Transport_Ztek implements IComm {
    private static D2xxManager ftdid2xx = null;
    private FT_Device ftDev = null;
    private static Context DeviceUARTContext = null;
    private static int DevCount = 0;

    public static int ListUsbDevice(Context ctx, int vid, int pid) {
        try {
            ftdid2xx = D2xxManager.getInstance(ctx);
        } catch (com.ftdi.j2xx.D2xxManager.D2xxException e) {
            return 0;
        }
        int tempDevCount = ftdid2xx.createDeviceInfoList(ctx);
        if (tempDevCount <= 0) return 0;
        if (!ftdid2xx.setVIDPID(vid, pid)) return 0;
        DevCount = tempDevCount;
        DeviceUARTContext = ctx;
        return DevCount;
    }

    public int Connect(int port, int baud, String frame) {
        if (frame.length() != 3) return -3;
        byte dataBits = 0, stopBits = 0, parity = 0;
        switch (frame.charAt(0)) {
            case '7':
                dataBits = 7;
                break;
            case '8':
                dataBits = 8;
                break;
            default:
                return -3;
        }
        switch (frame.charAt(1)) {
            case 'N':
                parity = 0;
                break;
            case 'E':
                parity = 2;
                break;
            case 'O':
                parity = 1;
                break;
            default:
                return -3;
        }
        switch (frame.charAt(2)) {
            case '1':
                stopBits = 0;
                break;
            case '2':
                stopBits = 2;
                break;
            default:
                return -3;
        }
        if (DevCount < port) return -3;
        this.ftDev = ftdid2xx.openByIndex(DeviceUARTContext, port - 1);
        if (this.ftDev == null || !this.ftDev.isOpen()) return -2;
        this.ftDev.setBitMode((byte) 0, (byte) 0);
        this.ftDev.setBaudRate(baud);
        this.ftDev.setDataCharacteristics(dataBits, stopBits, parity);
        this.ftDev.setFlowControl((short) 0, (byte) 11, (byte) 13);
        return 0;
    }

    public int Send(byte[] buffer, int offset, int m_count) {
        byte[] bufferWrite = new byte[m_count];
        System.arraycopy(buffer, offset, bufferWrite, 0, m_count);
        int iret = this.ftDev.write(bufferWrite, m_count);
        return (iret == m_count) ? 0 : -2;
    }

    public int Receive(byte[] bufferRead, int LenToRecv) {
        int lenTmp = this.ftDev.getQueueStatus();
        if (lenTmp < 0) return -2;
        if (lenTmp > LenToRecv) lenTmp = LenToRecv;
        final int iavailable = lenTmp;
        if (iavailable <= 0) return 0;
        final byte[] bufferRecv = new byte[iavailable];
        class ReadDataThrd extends Thread {
            public int mRecvLen = -1;

            public void run() {
                this.mRecvLen = Transport_Ztek.this.ftDev.read(bufferRecv, iavailable);
            }
        }
        ;
        ReadDataThrd readThrd = new ReadDataThrd();
        readThrd.start();
        try {
            readThrd.join();
        } catch (InterruptedException interruptedException) {
        }
        int recvLen = readThrd.mRecvLen;
        readThrd = null;
        if (recvLen > 0) System.arraycopy(bufferRecv, 0, bufferRead, 0, recvLen);
        return recvLen;
    }

    public int DisConnect() {
        if (this.ftDev.isOpen()) this.ftDev.close();
        this.ftDev = null;
        return 0;
    }

    public void ResetInputStream() {
        byte[] b;
        do b = new byte[256]; while (Receive(b, b.length) > 0);
    }
}
